package com.foreknow.test;

import java.awt.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

/**
 * Java中的反射：它是Java中非常重要的一个概念，它是具有动态机制的
 * 特点：
 *  1. 程序在运行的时候会判断任意一对象所属的类
 *  2. 程序在运行的时候可以动态获取类的对象
 *  3. 程序在运行的时候可以动态获取类中的方法以及属性
 *
 *  Java中反射的常见写法：
 *  1. Class clazz = 类名.class
 *  2. Class clazz = class.forName("com.mysql.jdbc.Driver");
 *  3. this.getClass()
 */
public class ReflectDemo {


    public void getMethodTest() throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
//        //1. 获取当前类的对象
        Class cls = Class.forName("com.foreknow.test.ReflectDemo");
        //2. 调用Class类对象中的 Method getMethod(String name, Class<?>... parameterTypes) 来获取到方法的名称以及参数
        // name - 方法名  parameterTypes - 参数列表
        Class[] parameterTypes = new Class[2];
        parameterTypes[0] = Class.forName("java.lang.String");
        parameterTypes[1] = Class.forName("java.util.HashMap");
        Method method = cls.getMethod("testMethod",parameterTypes);  //获取方法名以及这个方法的参数列表

        Object[] args = new Object[2]; //表示要调用方法会传递的实际参数
        args[0] = "hello tom";
        Map<String,String> ht = new HashMap<>();
        ht.put("name","this is map");
        args[1] = ht;
        //3. 调用testMethod方法
        String str = (String)method.invoke(new ReflectDemo(),args);
        System.out.println(str);



//        ReflectDemo rd = new ReflectDemo();
//        Map<String,String> ht = new HashMap<>();
//        ht.put("name","this is map");
//        String str = rd.testMethod("hello tom",ht);
//        System.out.println(str);

    }

    public String testMethod(String str, HashMap ht) {
        String returnStr = "this is return value";
        System.out.println("call() testMethod method");
        System.out.println("str="+str);
        System.out.println("name"+ht.get("name"));
        return returnStr;
    }

    public void getNameTest() throws ClassNotFoundException {
        String name = "这是一个反射测试";
        Class cls = name.getClass();
        System.out.println("String的类名是："+cls.getName());

        Button btn = new Button();
        Class btnClass = btn.getClass();
        System.out.println("Button class name is:"+btnClass.getName());

        Class superBtnClass = btnClass.getSuperclass();
        System.out.println("Button Super Class is : "+ superBtnClass.getName());

        Class clsTest = Class.forName("java.awt.Button");
        System.out.println("clsTest is: "+clsTest.getName());

    }

    public static void main(String[] args) {
        ReflectDemo reflectDemo = new ReflectDemo();
        try {
            reflectDemo.getMethodTest();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

//        try {
//            reflectDemo.getNameTest();
//        } catch (ClassNotFoundException e) {
//            e.printStackTrace();
//        }
    }
}
